<?
/**
 * This file is part of XNAT light.
 *
 * XNAT light is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XNAT light is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XNAT light.  If not, see <http://www.gnu.org/licenses/>.
 */
namespace NRG\Framework\Routers;

use NRG\Framework\Exceptions\IllegalArgumentException as IllegalArgumentException;
use NRG\Framework\Exceptions\RouterException as RouterException;
use NRG\Framework\Common\Registry as Registry;
use NRG\Framework\Controllers as Controllers;

/**
 * MVC router
 *
 * @package NRG\Framework\Routers
 */
class MVC
{
    /**
     * User request
     *
     * @var array
     */
    protected $_request;

    /**
     * URL base
     *
     * @var string
     */
    protected $_base;

    /**
     * Part of URI to exclude from route
     *
     * @var array
     */
    protected $_exclude;

    /**
     * Request URI
     *
     * @var string
     */
    protected $_uri;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->_exclude = array("api");
    }

    /**
     * Prepare the routing
     */
    protected function prepare()
    {
        // process and parse URL
        $parsed_url = parse_url("http://" . $_SERVER["SERVER_ADDR"] . $_SERVER["REQUEST_URI"]);
        $uri = preg_replace('@/{2,}@', '/', $parsed_url["path"]);
        $uri = trim($uri, "/");

        // explode the request
        $this->_request = explode("/", $uri);

        $this->_request = array_diff($this->_request, $this->_exclude);
        $this->_request = array_values($this->_request);

        Registry::put("baseurl", "");
    }

    /**
     * Part of URL to exclude from route
     *
     * @param $exclude string
     */
    public function exclude($exclude)
    {
	if(!is_string($exclude))
	    throw new IllegalArgumentException("Exclude must be a string");

        $exclude = trim($exclude, " \t\n\r\0\x0B");

	if($exclude == "")
	    return;

	$exploded = explode("/", $exclude);

	foreach($exploded as $token)
	{
	    $token = trim($token);

	    if($token != "")
		$this->_exclude[] = $token;
	}
    }

    /**
     * Route
     */
    public function route()
    {
        $this->prepare();

        if($this->_request[0] == "")
            $controllerName = "Index";
        else
            $controllerName = $this->_request[0];

        $controller = "NRG\\Framework\\Controllers\\$controllerName";

        array_shift($this->_request);

        try
        {
            // check if the controller exists
            if(! class_exists($controller, false))
                __autoload($controller);
        }
        catch(\Exception $e)
        {
            $e = new RouterException(RouterException::NO_CONTROLLER, $controllerName);

            $controller = new Controllers\Error($e);

            return;
        }

        $controller = new $controller($this->_request);
        $controller->dispatch();
    }
}
